package irc ;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import jvn.client.interfaces.JvnObjectI;
import jvn.client.JvnObjectImpl;
import jvn.client.interfaces.JvnObjectI;
import jvn.client.JvnServerImpl;
import jvn.client.JvnException;
import jvn.client.JvnAdvencedSharedObject;
import jvn.client.State;

//import spÃ©cifiques Ã  l'objet:

public class Jvn_Sentence extends Sentence implements JvnAdvencedSharedObject{

private static final long serialVersionUID = 1L;
private JvnObjectI jvnObjectImpl;
private JvnServerImpl jvnServerImpl;
private static String sharedObjectName = "irc";
private irc.Sentence sharedObjectBackUp = null;
private boolean autolock = true;

	
/**
 * Les constructeurs
 */
	
	public Jvn_Sentence  ( 
			)  throws jvn.client.JvnException
    {
		
			jvnServerImpl = JvnServerImpl.jvnGetServer();
			
			jvnObjectImpl = jvnServerImpl.jvnLookupObject(sharedObjectName);

				if (jvnObjectImpl == null) {
					
					irc.Sentence sharedObject =
							
							new Sentence(
								 								  );
					
					
					jvnObjectImpl = jvnServerImpl.jvnCreateObject(sharedObject);
					// after creation, I have a write lock on the object
					
					
					autolock = false;
					jvnUnLock();
					autolock = true;
					jvnServerImpl.jvnRegisterObject(sharedObjectName, jvnObjectImpl);
				}
	
		
    }
	public Jvn_Sentence  ( 
			     		java.lang.String p0
				     , 		int p1
				)  throws jvn.client.JvnException
    {
		
			jvnServerImpl = JvnServerImpl.jvnGetServer();
			
			jvnObjectImpl = jvnServerImpl.jvnLookupObject(sharedObjectName);

				if (jvnObjectImpl == null) {
					
					irc.Sentence sharedObject =
							
							new Sentence(
								 								 								  								 p0
								 								 								  , 								 p1
								 								  );
					
					
					jvnObjectImpl = jvnServerImpl.jvnCreateObject(sharedObject);
					// after creation, I have a write lock on the object
					
					
					autolock = false;
					jvnUnLock();
					autolock = true;
					jvnServerImpl.jvnRegisterObject(sharedObjectName, jvnObjectImpl);
				}
	
		
    }
	
	
	
	
	
	
/**
 * Les mÃ©thodes
 */

	@Override
	public void write  ( 
			     		java.lang.String p0
				)  throws jvn.client.JvnException
    {
				try{
			
					if (autolock){
				autolock = false;
			jvnLockWrite();
			autolock = true;
			}
			
			if (!(((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.WLT))){
				throw new JvnException("Warning, you do a write without a write lock. You don't write into the shared object.");
			}
					
				((Sentence)jvnObjectImpl.jvnGetObjectState()).write(
		 		 		  		 p0
		 		  );
		}
		finally{
			if (autolock){
				autolock = false;
			jvnUnLock();
			autolock = true;
			}
		}
				
		
    }
	@Override
	public java.lang.String read  ( 
			)  throws jvn.client.JvnException
    {
					java.lang.String retour;
				try{
			
					if (autolock){
				autolock = false;
			jvnLockRead();
			autolock = true;
			}
			if (!(((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.RLT)||((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.RLT_WLC) || ((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.WLT))){
				throw new JvnException("Warning, you do a read without a read lock, or a write lock. You can read an old value.");
			}
					
					retour = 
				((Sentence)jvnObjectImpl.jvnGetObjectState()).read(
		 		  );
		}
		finally{
			if (autolock){
				autolock = false;
			jvnUnLock();
			autolock = true;
			}
		}
					return retour;
				
		
    }
	@Override
	public java.lang.String read2  ( 
			)  throws jvn.client.JvnException
    {
					java.lang.String retour;
				try{
			
					if (autolock){
				autolock = false;
			jvnLockRead();
			autolock = true;
			}
			if (!(((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.RLT)||((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.RLT_WLC) || ((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().equals(State.WLT))){
				throw new JvnException("Warning, you do a read without a read lock, or a write lock. You can read an old value.");
			}
					
					retour = 
				((Sentence)jvnObjectImpl.jvnGetObjectState()).read2(
		 		  );
		}
		finally{
			if (autolock){
				autolock = false;
			jvnUnLock();
			autolock = true;
			}
		}
					return retour;
				
		
    }

/**
 * Les options avancÃ©es
 */

@Override
public void jvnSetAutolock(boolean b) throws JvnException {
	if (transaction){
		throw new JvnException("You cannot ask it during a transaction. Do a commit/rollback.");
	}
	this.autolock = b;

}


@Override
public void jvnUnLock() throws JvnException {
	if (transaction){
		throw new JvnException("You cannot ask it during a transaction. Do a commit/rollback.");
	}
	if (autolock){
		throw new JvnException("You cannot ask it when autolock is enable.");
	}
	jvnObjectImpl.jvnUnLock();
}

@Override
public void jvnLockRead() throws JvnException {
	if (transaction){
		throw new JvnException("You cannot ask it during a transaction. Do a commit/rollback.");
	}
	if (autolock){
		throw new JvnException("You cannot ask it when autolock is enable.");
	}
	jvnObjectImpl.jvnLockRead();
}

@Override
public void jvnLockWrite() throws JvnException {
	if (transaction){
		throw new JvnException("You cannot ask it during a transaction. Do a commit/rollback.");
	}
	if (autolock){
		throw new JvnException("You cannot ask it when autolock is enable.");
	}
	jvnObjectImpl.jvnLockWrite();
}
boolean transaction = false;



public static void jvnRename(String sharedObjectNameN) {
	sharedObjectName = sharedObjectNameN;

}

boolean lastautolock;

@Override
public void jvnBeginTransaction() throws JvnException {
	if (transaction){
		throw new JvnException("You cannot ask it during a transaction. Do a commit/rollback.");
	}
	try {
		jvnObjectImpl.jvnLockWrite();
		lastautolock = autolock;
		this.autolock = false;
		transaction = true;

	
		// Write to disk with FileOutputStream
		FileOutputStream f_out = new 
			FileOutputStream("myobject.data");

		// Write object with ObjectOutputStream
		ObjectOutputStream obj_out = new
			ObjectOutputStream (f_out);


	// Write object out to disk
	obj_out.writeObject ( jvnObjectImpl.jvnGetObjectState());	//TODO
	//sharedObjectBackUp = (irc.Sentence) ((Sentence)jvnObjectImpl.jvnGetObjectState()).;
	
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

@Override
public void jvnCommit() throws JvnException {
	transaction = false;
	jvnObjectImpl.jvnUnLock();
	 autolock = lastautolock;


}

public static void jvnQuit() throws JvnException {
	
	JvnServerImpl.jvnGetServer().jvnTerminate();

}

@Override
public void jvnRollBack() throws JvnException {
	try {

		// Read from disk using FileInputStream
		FileInputStream f_in = new 
			FileInputStream("myobject.data");

		// Read object using ObjectInputStream
		ObjectInputStream obj_in = 
			new ObjectInputStream (f_in);

		// Read an object
		Object obj = obj_in.readObject();


	if (obj instanceof Sentence)
	{
		// Cast object to a Vector
		jvnObjectImpl.jvnSetObjectState((Sentence) obj);

		// Do something with vector....
	}} catch (IOException | ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	transaction = false;
	autolock = lastautolock;
}

@Override
public String jvnGetLockState() {
	return ((JvnObjectImpl)jvnObjectImpl).jvnDebugGetLockState().toString();
}

}